﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IWMAG.Scripting.AST.ObjectModel;
using IWMAG.Scripting.Types;
using IWMAG.Scripting.Interpreter;
using IWMAG.Scripting.Compiler.UserInfo;

namespace IWMAG.Scripting.AST.Statements {
    internal class IfStatement : CodeStatement {
        public CodeExpression Condition;
        public CodeStatement ThenBody;
        public CodeStatement ElseBody;

        public IfStatement(Compiler.Lexeme l, CodeExpression expr, CodeStatement then, CodeStatement els)
            : base(l) {
            Condition = expr;
            ThenBody = then;
            ElseBody = els;
        }

        public override void Verify(Helpers.CompileTable sym, List<Compiler.IUserInfo> error) {
            Condition.Verify(sym, error);
            ThenBody.Verify(sym, error);
            if (ElseBody != null) {
                ElseBody.Verify(sym, error);
            }

            if (Condition.TypeOf() != CodeType.Bool) {
                SendError(error, Rules.IfStatementArgumentMustBeBool);
            }
        }

        public override IEnumerable<Continuation> Execute(ScriptEngine engine, Helpers.RuntimeTable sym) {
            Reference<RunValue> res = new Reference<RunValue>(RunValue.NoValue);

            foreach (Continuation wait in Condition.ValueOf(engine, sym, res)) yield return wait;

            CodeStatement todo = res.ReferencedValue.BoolValue ? ThenBody : ElseBody;

            if (todo != null) {
                foreach (Continuation wait in todo.Execute(engine, sym)) {
                    yield return wait;
                }
            }
        }
    }
}
